package flex.cc.vehicle_svr.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

import flex.cc.basicinformation.dao.ChannelDao;
import flex.cc.basicinformation.entity.ChannelEntity;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;

import flex.cc.PublicUtil;
import flex.cc.base.dto.LoginAuthDto;
import flex.cc.basicinformation.dao.ServiceProviderDataDao;
import flex.cc.basicinformation.entity.ServiceProviderDataEntity;
import flex.cc.basicinformation.entity.ServiceProviderEntity;
import flex.cc.basicinformation.service.ServiceProviderService;
import flex.cc.common.Constants;
import flex.cc.common.utils.CommonUtils;
import flex.cc.common.utils.OpenApiConf;
import flex.cc.common.utils.OpenApiUtil;
import flex.cc.common.utils.OrderNoGenerateUtil;
import flex.cc.common.utils.TypeConverUtils;
import flex.cc.core.utils.RequestUtil;
import flex.cc.fenfa.dto.RuleCountEntity;
import flex.cc.fenfa.dto.ServicerCountEntity;
import flex.cc.fenfa.service.RuleCountService;
import flex.cc.fenfa.service.ServicerCountService;
import flex.cc.fenfa.util.FenFaUtil;
import flex.cc.order.manage.dao.OrderCustomerDao;
import flex.cc.order.manage.dao.OrderMainDao;
import flex.cc.order.manage.dao.OrderPolicyDao;
import flex.cc.order.manage.dao.OrderRescueDao;
import flex.cc.order.manage.dao.OrderServiceProviderDao;
import flex.cc.order.manage.dao.OrderServiceRescueDao;
import flex.cc.order.manage.dao.OrderTrackDao;
import flex.cc.order.manage.dto.order.OrderCustomerEntity;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderPolicyEntity;
import flex.cc.order.manage.dto.order.OrderRescueEntity;
import flex.cc.order.manage.dto.order.OrderServiceProviderEntity;
import flex.cc.order.manage.dto.order.OrderServiceRescueEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.dto.vo.OrderRescuerVo;
import flex.cc.system.entity.DictCodeEntity;
import flex.cc.system.service.DictCodeService;
import flex.cc.vehicle_svr.service.InputService;

/**
 * @author wkangle
 * @className InputServiceImpl
 * @description 下单
 * @time 2021-09-06 18:50:05
 */
@Service("inputService")
@Transactional(rollbackFor = Exception.class)
public class InputServiceImpl implements InputService {
    private static final Logger logger = LoggerFactory.getLogger(InputServiceImpl.class);

    @Autowired
    private OrderMainDao orderMainDao;
    @Autowired
    private OrderPolicyDao orderPolicyDao;
    @Autowired
    protected OrderRescueDao orderRescueDao;
    @Autowired
    private OrderCustomerDao orderCustomerDao;
    @Autowired
    private OrderTrackDao orderTrackDao;
    @Autowired
    private OrderServiceRescueDao orderServiceRescueDao;
    @Autowired
    private OrderServiceProviderDao orderServiceProviderDao;
    @Autowired
    private OrderNoGenerateUtil orderNoGenerateUtil;
    @Autowired
    private TypeConverUtils typeConverUtils;
    @Autowired
    private DictCodeService dictCodeService;

    @Value("${pengda.createRescue}")
    private String createRescue;

    @Value("${serviceprovider.pengda.serverId}")
    private String serverId;

    @Value("${serviceprovider.pengda.serverName}")
    private String serverName;
    @Autowired
    private FenFaUtil fenFaUtil;
    @Autowired
    private ServiceProviderService serviceProviderService;
    @Autowired
    private ServiceProviderDataDao serviceProviderDataDao;
    @Autowired
    private RuleCountService ruleCountService;
    @Autowired
    private ServicerCountService servicerCountService;
    @Autowired
    private ChannelDao channelDao;

    /**
     * @description 上游下单接口相关业务处理
     * @param requestBodyMap 下单接口请求体
     * @param clientId 渠道来源识别码
     * @return
     * @author wkangle
     * @time 2021/09/08 0008 9:58
     * @exception/throws
    */
    @Override
    public String inputOrder(Map<String, Object> requestBodyMap) {
        Date currentDate = new Date();
        DictCodeEntity dictCodeEntity = dictCodeService.searchAllCodeByTypeCode("sourceName", "01", 0, null); // 取消接口的操作人是渠道商名称 TODO 默认渠道名称是电话中心-01
        String sourceName01 = dictCodeEntity.getValue();

        String ownerOrderNo = PublicUtil.isNotEmpty(requestBodyMap.get("ownerOrderNo")) ? requestBodyMap.get("ownerOrderNo").toString() : null; // 判断是否重复
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("ownerOrderNo", ownerOrderNo);
        OrderMainEntity oneByParams = orderMainDao.getOneByParams(param);
        if (PublicUtil.isNotEmpty(oneByParams)) {
            // 服务单轨迹表
            saveTrack("", "00", "来源单号重复[下单接口]：" + ownerOrderNo, "01", new Date(), sourceName01); // 下单备注； 待处理 TODO 来源单号重复
            return "{\"resultCode\":\"1\",\"message\":\"来源单号重复，下单失败\"}";
        }

        String orderNo = orderNoGenerateUtil.getOrderNo("01"); // TODO 默认渠道名称是电话中心-01

        if (PublicUtil.isNotEmpty(orderNo)) {

            // 服务单主表
            OrderMainEntity orderMainEntity = new OrderMainEntity();
            orderMainEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
            orderMainEntity.setOrderNo(orderNo);
            orderMainEntity.setOwnerOrderNo(ownerOrderNo);
            orderMainEntity.setOwnerSubOrderNo(PublicUtil.isNotEmpty(requestBodyMap.get("ownerSubOrderNo")) ? requestBodyMap.get("ownerSubOrderNo").toString() : null);
            orderMainEntity.setOperatorId(PublicUtil.isNotEmpty(requestBodyMap.get("operatorId")) ? requestBodyMap.get("operatorId").toString() : null);
            orderMainEntity.setSourceName("01"); // TODO 默认渠道名称是电话中心-01
            orderMainEntity.setIsManual(0); // 手工单，1-是 0-否
            String incidentType = PublicUtil.isNotEmpty(requestBodyMap.get("incidentType")) ? requestBodyMap.get("incidentType").toString() : null;
            orderMainEntity.setIncidentType(PublicUtil.isNotEmpty(incidentType) ? ("0".equals(incidentType) ? 0 : "1".equals(incidentType) ? 1 : null) : null);
            String serviceType = PublicUtil.isNotEmpty(requestBodyMap.get("serviceType")) ? requestBodyMap.get("serviceType").toString() : null;
            serviceType = TypeConverUtils.getServiceType("01", serviceType);
            requestBodyMap.put("serviceType", serviceType);
            orderMainEntity.setServiceItem(serviceType);
            orderMainEntity.setStatus("01"); // 待处理
            orderMainEntity.setUrgeCount(0); // 默认催单次数为0
            orderMainEntity.setBranch(PublicUtil.isNotEmpty(requestBodyMap.get("branch")) ? requestBodyMap.get("branch").toString() : null);
            orderMainEntity.setBranchName(PublicUtil.isNotEmpty(requestBodyMap.get("branchName")) ? requestBodyMap.get("branchName").toString() : null);
            orderMainEntity.setProvince(PublicUtil.isNotEmpty(requestBodyMap.get("province")) ? requestBodyMap.get("province").toString() : null);
            orderMainEntity.setCity(PublicUtil.isNotEmpty(requestBodyMap.get("city")) ? requestBodyMap.get("city").toString() : null);
            orderMainEntity.setDistrict(PublicUtil.isNotEmpty(requestBodyMap.get("district")) ? requestBodyMap.get("district").toString() : null);
            orderMainEntity.setCheckerName(PublicUtil.isNotEmpty(requestBodyMap.get("checkerName")) ? requestBodyMap.get("checkerName").toString() : null);
            orderMainEntity.setCheckerPhone(PublicUtil.isNotEmpty(requestBodyMap.get("checkerPhone")) ? requestBodyMap.get("checkerPhone").toString() : null);
            orderMainEntity.setIsDalayed(0); // 延时单，默认0-非延时，1-延时

            orderMainEntity.setVersion(1);
            orderMainEntity.setIfNewVersion(1);
            orderMainEntity.setIsDelete(0);
            orderMainEntity.setCreateTime(currentDate);
            orderMainEntity.setCreater(sourceName01);
            orderMainEntity.setUpdateTime(currentDate);
            orderMainEntity.setUpdater(sourceName01);
            orderMainDao.insert(orderMainEntity);

            // 服务单保单信息表
            OrderPolicyEntity orderPolicyEntity = new OrderPolicyEntity();
            orderPolicyEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
            orderPolicyEntity.setOrderNo(orderNo);
            orderPolicyEntity.setInsured(PublicUtil.isNotEmpty(requestBodyMap.get("insuredName")) ? requestBodyMap.get("insuredName").toString() : null);
            orderPolicyEntity.setCarNo(PublicUtil.isNotEmpty(requestBodyMap.get("vehicleNo")) ? requestBodyMap.get("vehicleNo").toString() : null);
            orderPolicyEntity.setCarModel(PublicUtil.isNotEmpty(requestBodyMap.get("vehicleType")) ? requestBodyMap.get("vehicleType").toString() : null);
            orderPolicyEntity.setCarVin(PublicUtil.isNotEmpty(requestBodyMap.get("vin")) ? requestBodyMap.get("vin").toString() : null);
            orderPolicyEntity.setPolicyNumber(PublicUtil.isNotEmpty(requestBodyMap.get("policyNumber")) ? requestBodyMap.get("policyNumber").toString() : null);

            orderPolicyEntity.setVersion(1);
            orderPolicyEntity.setIfNewVersion(1);
            orderPolicyEntity.setIsDelete(0);
            orderPolicyEntity.setCreateTime(currentDate);
            orderPolicyEntity.setCreater(sourceName01);
            orderPolicyEntity.setUpdateTime(currentDate);
            orderPolicyEntity.setUpdater(sourceName01);
            orderPolicyDao.insert(orderPolicyEntity);

            // 服务单客户信息表
            OrderCustomerEntity orderCustomerEntity = new OrderCustomerEntity();
            orderCustomerEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
            orderCustomerEntity.setOrderNo(orderNo);
            orderCustomerEntity.setUsername(PublicUtil.isNotEmpty(requestBodyMap.get("reporterName")) ? requestBodyMap.get("reporterName").toString() : null);
            orderCustomerEntity.setMobile(PublicUtil.isNotEmpty(requestBodyMap.get("reporterPhone")) ? requestBodyMap.get("reporterPhone").toString() : null);
            orderCustomerEntity.setIdCard(PublicUtil.isNotEmpty(requestBodyMap.get("reporterIdNo")) ? requestBodyMap.get("reporterIdNo").toString() : null);

            orderCustomerEntity.setVersion(1);
            orderCustomerEntity.setIfNewVersion(1);
            orderCustomerEntity.setIsDelete(0);
            orderCustomerEntity.setCreateTime(currentDate);
            orderCustomerEntity.setCreater(sourceName01);
            orderCustomerEntity.setUpdateTime(currentDate);
            orderCustomerEntity.setUpdater(sourceName01);
            orderCustomerDao.insert(orderCustomerEntity);

            // 服务单待救援信息
            OrderRescueEntity orderRescueEntity = new OrderRescueEntity();
            orderRescueEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
            orderRescueEntity.setOrderNo(orderNo);
            orderRescueEntity.setAddrAddress(PublicUtil.isNotEmpty(requestBodyMap.get("caseLocation")) ? requestBodyMap.get("caseLocation").toString() : null);
            orderRescueEntity.setEnv(PublicUtil.isNotEmpty(requestBodyMap.get("dragEnvironment")) ? requestBodyMap.get("dragEnvironment").toString() : null);
            orderRescueEntity.setAddrProvince(PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince")) ? requestBodyMap.get("caseProvince").toString() : null);
            orderRescueEntity.setAddrCity(PublicUtil.isNotEmpty(requestBodyMap.get("caseCity")) ? requestBodyMap.get("caseCity").toString() : null);
            orderRescueEntity.setAddrCounty(PublicUtil.isNotEmpty(requestBodyMap.get("caseCounty")) ? requestBodyMap.get("caseCounty").toString() : null);
            Double caseLongitude = PublicUtil.isNotEmpty(requestBodyMap.get("caseLongitude")) ? Double.valueOf(requestBodyMap.get("caseLongitude").toString()) : null;
            orderRescueEntity.setAddrLongitude(caseLongitude);
            Double caseLatitude = PublicUtil.isNotEmpty(requestBodyMap.get("caseLatitude")) ? Double.valueOf(requestBodyMap.get("caseLatitude").toString()) : null;
            orderRescueEntity.setAddrLatitude(caseLatitude);
            orderRescueEntity.setDesAddress(PublicUtil.isNotEmpty(requestBodyMap.get("desAddress")) ? requestBodyMap.get("desAddress").toString() : null);
            orderRescueEntity.setDesProvince(PublicUtil.isNotEmpty(requestBodyMap.get("desState")) ? requestBodyMap.get("desState").toString() : null);
            orderRescueEntity.setDesCity(PublicUtil.isNotEmpty(requestBodyMap.get("desCity")) ? requestBodyMap.get("desCity").toString() : null);
            orderRescueEntity.setDesCounty(PublicUtil.isNotEmpty(requestBodyMap.get("desCounty")) ? requestBodyMap.get("desCounty").toString() : null);
            Double desLongitude = PublicUtil.isNotEmpty(requestBodyMap.get("desLongitude")) ? Double.valueOf(requestBodyMap.get("desLongitude").toString()) : null;
            orderRescueEntity.setDesLongitude(desLongitude);
            Double desLatitude = PublicUtil.isNotEmpty(requestBodyMap.get("desLatitude")) ? Double.valueOf(requestBodyMap.get("desLatitude").toString()) : null;
            orderRescueEntity.setDesLatitude(desLatitude);

            orderRescueEntity.setVersion(1);
            orderRescueEntity.setIfNewVersion(1);
            orderRescueEntity.setIsDelete(0);
            orderRescueEntity.setCreateTime(currentDate);
            orderRescueEntity.setCreater(sourceName01);
            orderRescueEntity.setUpdateTime(currentDate);
            orderRescueEntity.setUpdater(sourceName01);
            orderRescueDao.insert(orderRescueEntity);

            // 服务单服务信息表
            OrderServiceProviderEntity orderServiceProviderEntity = new OrderServiceProviderEntity();
            orderServiceProviderEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
            orderServiceProviderEntity.setOrderNo(orderNo);
            // TODO 默认鹏达，后期增加服务商时，根据分配规则处理此处服务商信息
            orderServiceProviderEntity.setServerId(serverId); // 服务商默认鹏达
            orderServiceProviderEntity.setServerName(serverName); // 服务商默认鹏达

            orderServiceProviderEntity.setFee(0.0); // 默认语句救援服务费0.0
            orderServiceProviderEntity.setServiceAmount(0.0); // 实际救援服务费用默认0.0
            orderServiceProviderEntity.setEmptyAmount(0.0); // 空驶费默认0.0

            orderServiceProviderEntity.setVersion(1);
            orderServiceProviderEntity.setIfNewVersion(1);
            orderServiceProviderEntity.setIsDelete(0);
            orderServiceProviderEntity.setCreateTime(currentDate);
            orderServiceProviderEntity.setCreater(sourceName01);
            orderServiceProviderEntity.setUpdateTime(currentDate);
            orderServiceProviderEntity.setUpdater(sourceName01);
            orderServiceProviderDao.insert(orderServiceProviderEntity);

            // 服务单实际救援信息表
            OrderServiceRescueEntity orderServiceRescueEntity = new OrderServiceRescueEntity();
            orderServiceRescueEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
            orderServiceRescueEntity.setOrderNo(orderNo);

            orderServiceRescueEntity.setVersion(1);
            orderServiceRescueEntity.setIfNewVersion(1);
            orderServiceRescueEntity.setIsDelete(0);
            orderServiceRescueEntity.setCreateTime(currentDate);
            orderServiceRescueEntity.setCreater(sourceName01);
            orderServiceRescueEntity.setUpdateTime(currentDate);
            orderServiceRescueEntity.setUpdater(sourceName01);
            orderServiceRescueDao.insert(orderServiceRescueEntity);

            // 服务单轨迹表
            saveTrack(orderNo,
                    "00",
                    PublicUtil.isNotEmpty(requestBodyMap.get("serviceContent")) ? requestBodyMap.get("serviceContent").toString() : null,
                    "01",
                    currentDate,
                    sourceName01);

            requestBodyMap.put("orderNo", orderNo); // 传到下游的服务单号，是车服系统的服务单号
            // 调用下游下单接口
            String allotRescueResult = this.allotRescue(createRescue, OpenApiConf.PD_PublicKey, requestBodyMap);

            if (allotRescueResult != null) {
                JSONObject resultObject = JSONObject.parseObject(allotRescueResult);

                Integer resultCode = Integer.valueOf(PublicUtil.isNotEmpty(resultObject.get("resultCode")) ? resultObject.get("resultCode").toString() : null);
                String message = PublicUtil.isNotEmpty(resultObject.get("message")) ? resultObject.get("message").toString() : null;

                if (resultCode == 0) {
                    // 记录轨迹
                    currentDate = new Date();
                    saveTrack(orderNo, "00", "调用下游下单，成功", "01", currentDate, sourceName01); // 下单备注； 待处理

                    orderMainEntity.setChildStatus("1");
                    orderMainEntity.setUpdater(sourceName01);
                    orderMainEntity.setUpdateTime(new Date());
                    orderMainDao.update(orderMainEntity); // 更新服务单子状态
                } else {
                    // 记录轨迹
                    currentDate = new Date();
                    saveTrack(orderNo, "00", "调用下游下单，失败：" + message, "01", currentDate, sourceName01); // 下单备注； 待处理

                    orderMainEntity.setChildStatus("0");
                    orderMainEntity.setUpdater(sourceName01);
                    orderMainEntity.setUpdateTime(new Date());
                    orderMainDao.update(orderMainEntity); // 更新服务单子状态
                }
            } else {
                // 记录轨迹
                currentDate = new Date();
                saveTrack(orderNo, "00", "调用下游下单，失败：下单接口返回为null", "01", currentDate, sourceName01); // 下单备注； 待处理

                orderMainEntity.setChildStatus("0");
                orderMainEntity.setUpdater(sourceName01);
                orderMainEntity.setUpdateTime(new Date());
                orderMainDao.update(orderMainEntity); // 更新服务单子状态
            }
            return allotRescueResult;

        } else {
            // 服务单轨迹表
            saveTrack(orderNo, "00", "服务单号生成异常", "01", currentDate, sourceName01); // 下单备注； 待处理
            return "{\"resultCode\":\"1\",\"message\":\"服务单号生成异常，下单失败\"}";
        }
    }

    /**
	*
	* @author WANGCONG
	* 2022年3月28日上午9:31:36
	* @desc 根据分发规则下单（上游来的单子）：分发前增加车牌号重复下单校验
	*/
    @Override
    public String inputOrder_V3(Map<String, Object> requestBodyMap, String clientId) {
        Date currentDate = new Date();
        if("SUN_HYJY_RESCUE".equals(clientId)){ //阳光的报文中，clientId=SUN_HYJY_RESCUE，以后新加的渠道，约定clientId为02、03传值
        	clientId = "01";
        }
        //中华clientId为ZH或02
        if("02".equals(clientId)){ //阳光的报文中，clientId=SUN_HYJY_RESCUE，以后新加的渠道，约定clientId为02、03传值
        	clientId = "02";
        }
        /**
         * 2022-04-21 13:21:08【2.2-新渠道中华】优化caseCity：
         * 1、若传来的caseProvince是直辖市（北京市、天津市、上海市）、且caseCity值是“市辖区”，将caseCity转为对应的caseProvince。
         * 2、若传来的caseProvince是直辖市（重庆市）、caseCity值是“市辖区”、且caseCounty值是XX县，将caseCity转为县。
         */
        String caseCity = "";
        if ("02".equals(clientId)) {
            if (PublicUtil.isNotEmpty(requestBodyMap.get("caseCity"))) {
                if (PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince"))
                        && "市辖区".equals(requestBodyMap.get("caseCity").toString().trim())
                        && ("北京市".equals(requestBodyMap.get("caseProvince").toString().trim())
                        || "天津市".equals(requestBodyMap.get("caseProvince").toString().trim())
                        || "上海市".equals(requestBodyMap.get("caseProvince").toString().trim()))) {
                    caseCity = requestBodyMap.get("caseProvince").toString().trim();
                    requestBodyMap.put("caseCity", caseCity);
                } else if (PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince"))
                        && "重庆市".equals(requestBodyMap.get("caseProvince").toString().trim())
                        && "市辖区".equals(requestBodyMap.get("caseCity").toString().trim())
                        && PublicUtil.isNotEmpty(requestBodyMap.get("caseCounty"))
                        && requestBodyMap.get("caseCounty").toString().trim().endsWith("县")) {
                    caseCity = "县";
                    requestBodyMap.put("caseCity", caseCity);
                } else {
                    caseCity = requestBodyMap.get("caseCity").toString().trim();
                }
            }
        } else { // 阳光不需要转译caseCity，若后续新增渠道商，此处注意是否需要转译 TODO
            caseCity = PublicUtil.isNotEmpty(requestBodyMap.get("caseCity")) ? requestBodyMap.get("caseCity").toString().trim() : "";
        }
        /** 2022/02/23 0023 18:10 【2.2-服务包配置需求】 判断渠道商状态，仅允许启用状态的渠道商下单 */
        Map<String, Object> params = new HashMap<>();
        params.put("clientId", clientId);
        ChannelEntity channelEntity = channelDao.getOneByParams(params);
        if(PublicUtil.isEmpty(channelEntity)){
        	return "{\"resultCode\":\"1\",\"message\":\"下单失败，渠道配置问题请联系运营人员\"}";
        }
        if (!"1".equals(channelEntity.getStatus())) {
            return "{\"resultCode\":\"1\",\"message\":\"下单失败，渠道配置问题请联系运营人员\"}";
        }
        DictCodeEntity dictCodeEntity = dictCodeService.searchAllCodeByTypeCode("sourceName", clientId, 0, null); // 取消接口的操作人是渠道商名称 TODO 默认渠道名称是电话中心-01
        String sourceName01 = dictCodeEntity.getValue();
        String ownerOrderNo = PublicUtil.isNotEmpty(requestBodyMap.get("ownerOrderNo")) ? requestBodyMap.get("ownerOrderNo").toString() : null; // 判断是否重复
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("ownerOrderNo", ownerOrderNo);
        OrderMainEntity oneByParams = orderMainDao.getOneByParams(param);
        if (PublicUtil.isNotEmpty(oneByParams)) {
            // 服务单轨迹表
            saveTrack("", "00", "此工单已受理，重复下单[下单接口]：" + ownerOrderNo, "01", new Date(), sourceName01); // 下单备注； 待处理 TODO 来源单号重复
            return "{\"resultCode\":\"1\",\"message\":\"此工单" + ownerOrderNo + "已受理，重复下单\"}";
        }
        String orderNo = orderNoGenerateUtil.getOrderNo(clientId); // TODO 默认渠道名称是电话中心-01
        OrderMainEntity orderMainEntity = new OrderMainEntity();
        orderMainEntity.setOrderNo(orderNo);
        String dataId = UUID.randomUUID().toString().replace("-", "");
        orderMainEntity.setDataId(dataId);
        if(PublicUtil.isNotEmpty(orderNo)) {
            /**
             * ADD WANGCONG 2022年3月28日9:20:16
             * 1、判断当前车牌号上一次派给哪家救援商，验证其是否满足服务项+地区；
             *    1.1、若满足直接派发；
             *    1.2、不满足，按之前分发规则走
             */
            LoginAuthDto loginUser = RequestUtil.getLoginUser();
            String url = "";
            String PD_PublicKey = "";
            String servicerName = "";
            String code = "";
            String ruleId = "";
            String servicerId = "";
            
            int verifyTime = 0;
    		boolean carNoBoolean = false;
    		boolean realServicer = false;
    		Map<String, Object> car_params = new HashMap<String, Object>();
    		car_params.put("typeCode", "carNoVerifyTime");
    		DictCodeEntity codeVo = dictCodeService.getOneByParams(car_params);
    		if(codeVo!=null && StringUtils.isNotEmpty(codeVo.getValue())){
    			try {
    				verifyTime = Integer.valueOf(codeVo.getValue());
            		carNoBoolean = true;
    			} catch (Exception e) {
    				carNoBoolean = false;
    			}
    		}
    		String carNo = PublicUtil.isNotEmpty(requestBodyMap.get("vehicleNo")) ? requestBodyMap.get("vehicleNo").toString() : null;
    		OrderRescuerVo rescuerVo = null;
    		if(carNoBoolean && verifyTime>0 && PublicUtil.isNotEmpty(carNo)){
            	rescuerVo = orderServiceProviderDao.findRepeatOrderByCarNo_V2(carNo, String.valueOf(verifyTime));
            }
    		if(PublicUtil.isNotEmpty(rescuerVo)){//说明当前车牌号之前派发过
    			servicerId = rescuerVo.getRescuerId();
    			Map<String, String> servicerParam = new HashMap<>();
            	servicerParam.put("servicerId", servicerId);
            	//add W 2022年4月21日13:43:47 判断当时的救援商是否满足救援单的服务项+服务地区
            	String serviceType = PublicUtil.isNotEmpty(requestBodyMap.get("serviceType")) ? requestBodyMap.get("serviceType").toString() : null;
            	serviceType = TypeConverUtils.getServiceType(clientId, serviceType);
            	String province = PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince")) ? requestBodyMap.get("caseProvince").toString().trim() : null;
            	String ctiy = "";
            	if ("02".equals(clientId)) {
            		ctiy = caseCity;
            	}else{
            		ctiy = PublicUtil.isNotEmpty(requestBodyMap.get("caseCity")) ? requestBodyMap.get("caseCity").toString().trim() : null;
            	}
            	String area = PublicUtil.isNotEmpty(requestBodyMap.get("caseCounty")) ? requestBodyMap.get("caseCounty").toString().trim() : null;
            	List<String> serviceItemList = Arrays.asList(serviceType.split(","));
            	List<String> provinceList = Arrays.asList(province.split(","));
            	List<String> cityList = Arrays.asList( PublicUtil.isNotEmpty(ctiy) ? ctiy.split(",") : null );
            	List<String> areaList = Arrays.asList( PublicUtil.isNotEmpty(area) ? area.split(",") : null );
            	Map<String, Object> provider_params = new HashMap<>();
            	provider_params.put("serviceItemList", serviceItemList);
            	provider_params.put("provinceList", provinceList);
            	provider_params.put("cityList", cityList);
            	provider_params.put("areaList", areaList);
            	provider_params.put("status", "1");
            	provider_params.put("servicerId", servicerId); //救援商主键
            	List<ServiceProviderEntity> servicerList = serviceProviderService.findMatchServicer(provider_params);
            	if(servicerList.size()>0){//当前救援商满足
            		realServicer = true;
            	}
    		}
            if(realServicer){//当前车牌号之前派发过，且救援商满足，直接给当时的救援商
            	servicerId = rescuerVo.getRescuerId();
        		servicerName = rescuerVo.getRescuerName();
        		Map<String, String> servicerParam = new HashMap<>();
            	servicerParam.put("servicerId", servicerId);
            	ServiceProviderEntity providerVo = serviceProviderService.findProviderByParam(servicerParam);
            	servicerName = providerVo.getServiceName();
            	PD_PublicKey = providerVo.getPk();
            	
            	saveOrderInformation(orderNo, "01", requestBodyMap, sourceName01, ownerOrderNo, currentDate, servicerId, servicerName, clientId, dataId);
            	
            	List<ServiceProviderDataEntity> urlList = serviceProviderDataDao.queryListByYwId(servicerId);
            	for(int i=0; i<urlList.size(); i++){
            		if(Constants.createRescue.equals(urlList.get(i).getUrlType())){
            			url = urlList.get(i).getUrl();
            			break;
            		}
            	}
            	if(PublicUtil.isEmpty(url)){
                    orderMainEntity.setChildStatus("0");
                    orderMainEntity.setUpdater(RequestUtil.getLoginUser().getUserCode());
                    orderMainEntity.setUpdateTime(new Date());
                    orderMainEntity.setStatus("00");
                    orderMainDao.update(orderMainEntity); // 更新服务单子状态
                    OrderTrackEntity orderTrackVo = new OrderTrackEntity();
                    orderTrackVo.setDataId(UUID.randomUUID().toString().replace("-", ""));
                    orderTrackVo.setOrderNo(orderMainEntity.getOrderNo());
                    orderTrackVo.setTrackType("00"); // 下单备注
                    orderTrackVo.setStatus("00"); // 派发失败
                    orderTrackVo.setTrackDesc("保存成功，但派单失败：相同车牌号下单未找到服务商["+servicerName+"]下单接口地址");
                    orderTrackVo.setIsDelete(0);
                    orderTrackVo.setCreateTime(currentDate);
                    orderTrackVo.setCreater(loginUser.getUserCode());
                    orderTrackVo.setUpdateTime(currentDate);
                    orderTrackVo.setUpdater(loginUser.getUserCode());
                    orderTrackDao.insert(orderTrackVo);
                    return "{\"resultCode\":\"3\",\"message\":\"保存成功，但派单失败：未找到服务商下单接口地址\"}";
            	}
            	code = "888";
        	}else{//此车牌号近期未下过单，按原有分发流程走
        		//TODO 根据渠道方、省市区、类型顺序匹配分发规则
        		Map<String, String> paramMap = new HashMap<>();
                paramMap.put("clientId", clientId);
                paramMap.put("province", PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince")) ? requestBodyMap.get("caseProvince").toString().trim() : "");
                // 2022-04-21 13:21:08【2.2-新渠道中华】优化caseCity
                // paramMap.put("city", PublicUtil.isNotEmpty(requestBodyMap.get("caseCity")) ? requestBodyMap.get("caseCity").toString().trim() : "");
                paramMap.put("city", caseCity);
                paramMap.put("area", PublicUtil.isNotEmpty(requestBodyMap.get("caseCounty")) ? requestBodyMap.get("caseCounty").toString().trim() : "");
                String param_serviceType = PublicUtil.isNotEmpty(requestBodyMap.get("serviceType")) ? requestBodyMap.get("serviceType").toString() : null;
                param_serviceType = TypeConverUtils.getServiceType("01", param_serviceType);
                paramMap.put("serviceItem", param_serviceType);
            	Map<String, String> fenfaMap = fenFaUtil.initChoiceServicerId(paramMap);
                code = fenfaMap.get("code"); //01：规则匹配到的；02：服务商信息匹配到的；03：未匹配到
                if("03".equals(code)){
                	//车服本地保存，状态为00(派发失败)
                	String msg = fenfaMap.get("msg");
                	// 保存上游下单请求参数，服务单主状态默认为00(派发失败)
                	saveOrderInformation(orderNo, "00", requestBodyMap, sourceName01, ownerOrderNo, currentDate, "", "", clientId, dataId);
                	saveTrack(orderNo, "00", msg, "00", currentDate, sourceName01);
                	return "{\"resultCode\":\"3\",\"message\":\"保存成功，但派单失败：没有匹配的服务商\"}";
                }else{
                	servicerId = fenfaMap.get("servicerId");
                	ruleId = fenfaMap.get("ruleId");
                	//根据服务商Id获取实体信息，拿到服务商名称、下单地址、公钥
                	Map<String, String> servicerParam = new HashMap<>();
                	servicerParam.put("servicerId", servicerId);
                	ServiceProviderEntity providerVo = serviceProviderService.findProviderByParam(servicerParam);
                	servicerName = providerVo.getServiceName();

                	// 保存上游下单请求参数，服务单主状态默认为01-待处理
                	saveOrderInformation(orderNo, "01", requestBodyMap, sourceName01, ownerOrderNo, currentDate, servicerId, servicerName, clientId, dataId);
                	PD_PublicKey = providerVo.getPk();
                	List<ServiceProviderDataEntity> urlList = serviceProviderDataDao.queryListByYwId(servicerId);
                	for(int i=0; i<urlList.size(); i++){
                		if(Constants.createRescue.equals(urlList.get(i).getUrlType())){
                			url = urlList.get(i).getUrl();
                			break;
                		}
                	}
                	if(PublicUtil.isEmpty(url)){
                		saveTrack(orderNo, "00", "调用下游下单失败：未找到服务商["+servicerName+"]下单接口地址", "01", currentDate, sourceName01);
                        orderMainEntity.setChildStatus("0");
                        orderMainEntity.setStatus("00");
                        orderMainEntity.setUpdater(sourceName01);
                        orderMainEntity.setUpdateTime(new Date());
                        orderMainDao.update(orderMainEntity); // 更新服务单子状态
                        return "{\"resultCode\":\"3\",\"message\":\"保存成功，但派单失败：未找到服务商下单接口地址\"}";
                	}
                }
        	}
            requestBodyMap.put("orderNo", orderNo); // 传到下游的服务单号，是车服系统的服务单号
            // 匹配到服务商的服务单，直接给上游返回成功，然后异步调用下游下单接口。
            this.callCreateRescue(orderNo, sourceName01, orderMainEntity, servicerId, servicerName,ruleId, code, url, PD_PublicKey, requestBodyMap);
            return "{\"resultCode\":\"0\",\"message\":\"成功\"}";
        }else {
            // 服务单轨迹表
            saveTrack(orderNo, "00", "服务单号生成异常", "01", currentDate, sourceName01); // 下单备注； 待处理
            return "{\"resultCode\":\"1\",\"message\":\"服务单号生成异常，下单失败\"}";
        }
    }

    /**
	*
	* @author WANGCONG
	* 2021年10月19日下午1:52:56
	* @desc 根据分发规则下单（上游来的单子）
	*/
    @Override
    public String inputOrder_V2(Map<String, Object> requestBodyMap, String clientId) {
        Date currentDate = new Date();
        if("SUN_HYJY_RESCUE".equals(clientId)){ //阳光的报文中，clientId=SUN_HYJY_RESCUE，以后新加的渠道，约定clientId为02、03传值
        	clientId = "01";
        }

        /** 2022/02/23 0023 18:10 【2.2-服务包配置需求】 判断渠道商状态，仅允许启用状态的渠道商下单 */
        Map<String, Object> params = new HashMap<>();
        params.put("clientId", clientId);
        ChannelEntity channelEntity = channelDao.getOneByParams(params);
        if (!"1".equals(channelEntity.getStatus())) {
            return "{\"resultCode\":\"1\",\"message\":\"下单失败，渠道配置问题请联系运营人员\"}";
        }

        DictCodeEntity dictCodeEntity = dictCodeService.searchAllCodeByTypeCode("sourceName", clientId, 0, null); // 取消接口的操作人是渠道商名称 TODO 默认渠道名称是电话中心-01
        String sourceName01 = dictCodeEntity.getValue();
        String ownerOrderNo = PublicUtil.isNotEmpty(requestBodyMap.get("ownerOrderNo")) ? requestBodyMap.get("ownerOrderNo").toString() : null; // 判断是否重复
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("ownerOrderNo", ownerOrderNo);
        OrderMainEntity oneByParams = orderMainDao.getOneByParams(param);
        if (PublicUtil.isNotEmpty(oneByParams)) {
            // 服务单轨迹表
            saveTrack("", "00", "来源单号重复[下单接口]：" + ownerOrderNo, "01", new Date(), sourceName01); // 下单备注； 待处理 TODO 来源单号重复
            return "{\"resultCode\":\"1\",\"message\":\"来源单号重复，下单失败\"}";
        }
        String orderNo = orderNoGenerateUtil.getOrderNo(clientId); // TODO 默认渠道名称是电话中心-01
        OrderMainEntity orderMainEntity = new OrderMainEntity();
        orderMainEntity.setOrderNo(orderNo);
        String dataId = UUID.randomUUID().toString().replace("-", "");
        orderMainEntity.setDataId(dataId);
        if(PublicUtil.isNotEmpty(orderNo)) {
        	Map<String, String> paramMap = new HashMap<>();
            paramMap.put("clientId", clientId);
            paramMap.put("province", PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince")) ? requestBodyMap.get("caseProvince").toString().trim() : "");
            paramMap.put("city", PublicUtil.isNotEmpty(requestBodyMap.get("caseCity")) ? requestBodyMap.get("caseCity").toString().trim() : "");
            paramMap.put("area", PublicUtil.isNotEmpty(requestBodyMap.get("caseCounty")) ? requestBodyMap.get("caseCounty").toString().trim() : "");
            String param_serviceType = PublicUtil.isNotEmpty(requestBodyMap.get("serviceType")) ? requestBodyMap.get("serviceType").toString() : null;
            param_serviceType = TypeConverUtils.getServiceType("01", param_serviceType);
            paramMap.put("serviceItem", param_serviceType);
            //TODO 根据渠道方、省市区、类型顺序匹配分发规则
        	Map<String, String> fenfaMap = fenFaUtil.initChoiceServicerId(paramMap);
            String code = fenfaMap.get("code"); //01：规则匹配到的；02：服务商信息匹配到的；03：未匹配到
            if("03".equals(code)){
            	//车服本地保存，状态为00(派发失败)
            	String msg = fenfaMap.get("msg");

            	// 保存上游下单请求参数，服务单主状态默认为00(派发失败)
            	saveOrderInformation(orderNo, "00", requestBodyMap, sourceName01, ownerOrderNo, currentDate, "", "", clientId, dataId);
            	saveTrack(orderNo, "00", msg, "00", currentDate, sourceName01);
            	return "{\"resultCode\":\"3\",\"message\":\"保存成功，但派单失败：没有匹配的服务商\"}";
            }else{
            	String servicerId = fenfaMap.get("servicerId");
            	String ruleId = fenfaMap.get("ruleId");
            	//根据服务商Id获取实体信息，拿到服务商名称、下单地址、公钥
            	Map<String, String> servicerParam = new HashMap<>();
            	servicerParam.put("servicerId", servicerId);
            	ServiceProviderEntity providerVo = serviceProviderService.findProviderByParam(servicerParam);
            	String servicerName = providerVo.getServiceName();

            	// 保存上游下单请求参数，服务单主状态默认为01-待处理
            	saveOrderInformation(orderNo, "01", requestBodyMap, sourceName01, ownerOrderNo, currentDate, servicerId, servicerName, clientId, dataId);
            	String PD_PublicKey = providerVo.getPk();
            	List<ServiceProviderDataEntity> urlList = serviceProviderDataDao.queryListByYwId(servicerId);
            	String url = "";
            	for(int i=0; i<urlList.size(); i++){
            		if(Constants.createRescue.equals(urlList.get(i).getUrlType())){
            			url = urlList.get(i).getUrl();
            			break;
            		}
            	}
            	if(PublicUtil.isEmpty(url)){
            		saveTrack(orderNo, "00", "调用下游下单失败：未找到服务商下单接口地址", "01", currentDate, sourceName01);
                    orderMainEntity.setChildStatus("0");
                    orderMainEntity.setStatus("00");
                    orderMainEntity.setUpdater(sourceName01);
                    orderMainEntity.setUpdateTime(new Date());
                    orderMainDao.update(orderMainEntity); // 更新服务单子状态
                    return "{\"resultCode\":\"3\",\"message\":\"保存成功，但派单失败：未找到服务商下单接口地址\"}";
            	}
                requestBodyMap.put("orderNo", orderNo); // 传到下游的服务单号，是车服系统的服务单号

                // 匹配到服务商的服务单，直接给上游返回成功，然后异步调用下游下单接口。
                this.callCreateRescue(orderNo, sourceName01, orderMainEntity, servicerId, servicerName,ruleId, code, url, PD_PublicKey, requestBodyMap);
                return "{\"resultCode\":\"0\",\"message\":\"成功\"}";
            }
        }else {
            // 服务单轨迹表
            saveTrack(orderNo, "00", "服务单号生成异常", "01", currentDate, sourceName01); // 下单备注； 待处理
            return "{\"resultCode\":\"1\",\"message\":\"服务单号生成异常，下单失败\"}";
        }
    }

    /**
	*
	* @author WANGCONG
	* 2021年10月19日上午11:24:52
	* @param orderNo 订单号
	* @param status 服务单状态
	* @param requestBodyMap 报文信息
	* @param sourceName 渠道商名称
	* @param ownerOrderNo 报文信息
	* @param currentDate 当前时间
	* @param servicerId 服务商Id
	* @param servicerName 服务商名称
	* @param clientId 区分渠道来源
	* @desc 保存服务单相关信息
	*/
    public void saveOrderInformation(String orderNo, String status, Map<String, Object> requestBodyMap, String sourceName,String ownerOrderNo,
    		Date currentDate, String servicerId, String servicerName, String clientId, String dataId) {
    	// 服务单主表
        OrderMainEntity orderMainEntity = new OrderMainEntity();
        orderMainEntity.setDataId(dataId);
        orderMainEntity.setOrderNo(orderNo);
        orderMainEntity.setOwnerOrderNo(ownerOrderNo);
        orderMainEntity.setOwnerSubOrderNo(PublicUtil.isNotEmpty(requestBodyMap.get("ownerSubOrderNo")) ? requestBodyMap.get("ownerSubOrderNo").toString() : null);
        orderMainEntity.setOperatorId(PublicUtil.isNotEmpty(requestBodyMap.get("operatorId")) ? requestBodyMap.get("operatorId").toString() : null);
        orderMainEntity.setSourceName(clientId); // TODO 默认渠道名称是电话中心-01
        orderMainEntity.setIsManual(0); // 手工单，1-是 0-否
        String incidentType = PublicUtil.isNotEmpty(requestBodyMap.get("incidentType")) ? requestBodyMap.get("incidentType").toString() : null;
        orderMainEntity.setIncidentType(PublicUtil.isNotEmpty(incidentType) ? ("0".equals(incidentType) ? 0 : "1".equals(incidentType) ? 1 : null) : null);
        String serviceType = PublicUtil.isNotEmpty(requestBodyMap.get("serviceType")) ? requestBodyMap.get("serviceType").toString() : null;
        serviceType = TypeConverUtils.getServiceType("01", serviceType);
        requestBodyMap.put("serviceType", serviceType);
        orderMainEntity.setServiceItem(serviceType);
        orderMainEntity.setStatus(status); // 01-待处理、00-派发失败
        orderMainEntity.setChildStatus("00".equals(status) ? "0" : "1");
        orderMainEntity.setUrgeCount(0); // 默认催单次数为0
        orderMainEntity.setBranch(PublicUtil.isNotEmpty(requestBodyMap.get("branch")) ? requestBodyMap.get("branch").toString() : null);
        orderMainEntity.setBranchName(PublicUtil.isNotEmpty(requestBodyMap.get("branchName")) ? requestBodyMap.get("branchName").toString() : null);
        orderMainEntity.setProvince(PublicUtil.isNotEmpty(requestBodyMap.get("province")) ? requestBodyMap.get("province").toString() : null);
        orderMainEntity.setCity(PublicUtil.isNotEmpty(requestBodyMap.get("city")) ? requestBodyMap.get("city").toString() : null);
        orderMainEntity.setDistrict(PublicUtil.isNotEmpty(requestBodyMap.get("district")) ? requestBodyMap.get("district").toString() : null);
        orderMainEntity.setCheckerName(PublicUtil.isNotEmpty(requestBodyMap.get("checkerName")) ? requestBodyMap.get("checkerName").toString() : null);
        orderMainEntity.setCheckerPhone(PublicUtil.isNotEmpty(requestBodyMap.get("checkerPhone")) ? requestBodyMap.get("checkerPhone").toString() : null);
        orderMainEntity.setIsDalayed(0); // 延时单，默认0-非延时，1-延时
        orderMainEntity.setVersion(1);
        orderMainEntity.setIfNewVersion(1);
        orderMainEntity.setIsDelete(0);
        orderMainEntity.setCreateTime(currentDate);
        orderMainEntity.setCreater(sourceName);
        orderMainEntity.setUpdateTime(currentDate);
        orderMainEntity.setUpdater(sourceName);
        orderMainDao.insert(orderMainEntity);
        // 服务单保单信息表
        OrderPolicyEntity orderPolicyEntity = new OrderPolicyEntity();
        orderPolicyEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderPolicyEntity.setOrderNo(orderNo);
        orderPolicyEntity.setInsured(PublicUtil.isNotEmpty(requestBodyMap.get("insuredName")) ? requestBodyMap.get("insuredName").toString() : null);
        orderPolicyEntity.setCarNo(PublicUtil.isNotEmpty(requestBodyMap.get("vehicleNo")) ? requestBodyMap.get("vehicleNo").toString() : null);
        orderPolicyEntity.setCarModel(PublicUtil.isNotEmpty(requestBodyMap.get("vehicleType")) ? requestBodyMap.get("vehicleType").toString() : null);
        orderPolicyEntity.setCarVin(PublicUtil.isNotEmpty(requestBodyMap.get("vin")) ? requestBodyMap.get("vin").toString() : null);
        orderPolicyEntity.setPolicyNumber(PublicUtil.isNotEmpty(requestBodyMap.get("policyNumber")) ? requestBodyMap.get("policyNumber").toString() : null);
        orderPolicyEntity.setVersion(1);
        orderPolicyEntity.setIfNewVersion(1);
        orderPolicyEntity.setIsDelete(0);
        orderPolicyEntity.setCreateTime(currentDate);
        orderPolicyEntity.setCreater(sourceName);
        orderPolicyEntity.setUpdateTime(currentDate);
        orderPolicyEntity.setUpdater(sourceName);
        orderPolicyDao.insert(orderPolicyEntity);
        // 服务单客户信息表
        OrderCustomerEntity orderCustomerEntity = new OrderCustomerEntity();
        orderCustomerEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderCustomerEntity.setOrderNo(orderNo);
        orderCustomerEntity.setUsername(PublicUtil.isNotEmpty(requestBodyMap.get("reporterName")) ? requestBodyMap.get("reporterName").toString() : null);
        orderCustomerEntity.setMobile(PublicUtil.isNotEmpty(requestBodyMap.get("reporterPhone")) ? requestBodyMap.get("reporterPhone").toString() : null);
        orderCustomerEntity.setIdCard(PublicUtil.isNotEmpty(requestBodyMap.get("reporterIdNo")) ? requestBodyMap.get("reporterIdNo").toString() : null);
        orderCustomerEntity.setVersion(1);
        orderCustomerEntity.setIfNewVersion(1);
        orderCustomerEntity.setIsDelete(0);
        orderCustomerEntity.setCreateTime(currentDate);
        orderCustomerEntity.setCreater(sourceName);
        orderCustomerEntity.setUpdateTime(currentDate);
        orderCustomerEntity.setUpdater(sourceName);
        orderCustomerDao.insert(orderCustomerEntity);
        // 服务单待救援信息
        OrderRescueEntity orderRescueEntity = new OrderRescueEntity();
        orderRescueEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderRescueEntity.setOrderNo(orderNo);
        orderRescueEntity.setAddrAddress(PublicUtil.isNotEmpty(requestBodyMap.get("caseLocation")) ? requestBodyMap.get("caseLocation").toString() : null);
        orderRescueEntity.setEnv(PublicUtil.isNotEmpty(requestBodyMap.get("dragEnvironment")) ? requestBodyMap.get("dragEnvironment").toString() : null);
        orderRescueEntity.setAddrProvince(PublicUtil.isNotEmpty(requestBodyMap.get("caseProvince")) ? requestBodyMap.get("caseProvince").toString() : null);
        orderRescueEntity.setAddrCity(PublicUtil.isNotEmpty(requestBodyMap.get("caseCity")) ? requestBodyMap.get("caseCity").toString() : null);
        orderRescueEntity.setAddrCounty(PublicUtil.isNotEmpty(requestBodyMap.get("caseCounty")) ? requestBodyMap.get("caseCounty").toString() : null);
        Double caseLongitude = PublicUtil.isNotEmpty(requestBodyMap.get("caseLongitude")) ? Double.valueOf(requestBodyMap.get("caseLongitude").toString()) : null;
        orderRescueEntity.setAddrLongitude(caseLongitude);
        Double caseLatitude = PublicUtil.isNotEmpty(requestBodyMap.get("caseLatitude")) ? Double.valueOf(requestBodyMap.get("caseLatitude").toString()) : null;
        orderRescueEntity.setAddrLatitude(caseLatitude);
        orderRescueEntity.setDesAddress(PublicUtil.isNotEmpty(requestBodyMap.get("desAddress")) ? requestBodyMap.get("desAddress").toString() : null);
        orderRescueEntity.setDesProvince(PublicUtil.isNotEmpty(requestBodyMap.get("desState")) ? requestBodyMap.get("desState").toString() : null);
        orderRescueEntity.setDesCity(PublicUtil.isNotEmpty(requestBodyMap.get("desCity")) ? requestBodyMap.get("desCity").toString() : null);
        orderRescueEntity.setDesCounty(PublicUtil.isNotEmpty(requestBodyMap.get("desCounty")) ? requestBodyMap.get("desCounty").toString() : null);
        Double desLongitude = PublicUtil.isNotEmpty(requestBodyMap.get("desLongitude")) ? Double.valueOf(requestBodyMap.get("desLongitude").toString()) : null;
        orderRescueEntity.setDesLongitude(desLongitude);
        Double desLatitude = PublicUtil.isNotEmpty(requestBodyMap.get("desLatitude")) ? Double.valueOf(requestBodyMap.get("desLatitude").toString()) : null;
        orderRescueEntity.setDesLatitude(desLatitude);
        orderRescueEntity.setVersion(1);
        orderRescueEntity.setIfNewVersion(1);
        orderRescueEntity.setIsDelete(0);
        orderRescueEntity.setCreateTime(currentDate);
        orderRescueEntity.setCreater(sourceName);
        orderRescueEntity.setUpdateTime(currentDate);
        orderRescueEntity.setUpdater(sourceName);
        orderRescueDao.insert(orderRescueEntity);
        // 服务单服务信息表
        OrderServiceProviderEntity orderServiceProviderEntity = new OrderServiceProviderEntity();
        orderServiceProviderEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderServiceProviderEntity.setOrderNo(orderNo);
        // TODO 默认鹏达，后期增加服务商时，根据分配规则处理此处服务商信息
        orderServiceProviderEntity.setServerId(servicerId); // 服务商默认鹏达
        orderServiceProviderEntity.setServerName(servicerName); // 服务商默认鹏达
        orderServiceProviderEntity.setFee(0.0); // 默认语句救援服务费0.0
        orderServiceProviderEntity.setServiceAmount(0.0); // 实际救援服务费用默认0.0
        orderServiceProviderEntity.setEmptyAmount(0.0); // 空驶费默认0.0
        orderServiceProviderEntity.setVersion(1);
        orderServiceProviderEntity.setIfNewVersion(1);
        orderServiceProviderEntity.setIsDelete(0);
        orderServiceProviderEntity.setCreateTime(currentDate);
        orderServiceProviderEntity.setCreater(sourceName);
        orderServiceProviderEntity.setUpdateTime(currentDate);
        orderServiceProviderEntity.setUpdater(sourceName);
        orderServiceProviderDao.insert(orderServiceProviderEntity);
        // 服务单实际救援信息表
        OrderServiceRescueEntity orderServiceRescueEntity = new OrderServiceRescueEntity();
        orderServiceRescueEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderServiceRescueEntity.setOrderNo(orderNo);
        orderServiceRescueEntity.setVersion(1);
        orderServiceRescueEntity.setIfNewVersion(1);
        orderServiceRescueEntity.setIsDelete(0);
        orderServiceRescueEntity.setCreateTime(currentDate);
        orderServiceRescueEntity.setCreater(sourceName);
        orderServiceRescueEntity.setUpdateTime(currentDate);
        orderServiceRescueEntity.setUpdater(sourceName);
        orderServiceRescueDao.insert(orderServiceRescueEntity);

        // 服务单轨迹表
        saveTrack(orderNo,
                "00",
                PublicUtil.isNotEmpty(requestBodyMap.get("serviceContent")) ? requestBodyMap.get("serviceContent").toString() : null,
                "01",
                currentDate,
                sourceName);
	}


	/**
     * 派单
     * */
    @Override
    public String allotRescue(String allot_rescue_url, String publicKey, Map<String, Object> requestBodyMap) {
        try {
        	// 事故类型：（鹏达）1-非事故，2-事故；（电话中心）0-非事故，1-事故
            Integer incidentType = PublicUtil.isNotEmpty(requestBodyMap.get("incidentType")) ? Integer.valueOf(requestBodyMap.get("incidentType").toString()) : null;
            incidentType = typeConverUtils.getIncidentType(serverId, incidentType); // TODO 服务商id

            // 服务类型转换
            String serviceType = PublicUtil.isNotEmpty(requestBodyMap.get("serviceType")) ? requestBodyMap.get("serviceType").toString() : null;
            Integer serviceItem = typeConverUtils.getServiceItem(serverId, serviceType); // TODO 服务商id

            Integer finalIncidentType = incidentType;
            Integer finalServiceItem = serviceItem;
            Map<String, Object> param = new HashMap<String, Object>(){{
                put("orderNo", requestBodyMap.get("orderNo"));
                put("incidentType", finalIncidentType);
                put("serviceItem", finalServiceItem);
                put("env", requestBodyMap.get("dragEnvironment"));
                put("remark", PublicUtil.isNotEmpty(requestBodyMap.get("serviceContent")) ? requestBodyMap.get("serviceContent") : null);
                put("userInfo", OpenApiUtil.RSAEncryptOAEP(CommonUtils.toJSONString(new HashMap<String, Object>(){{
                    put("username", requestBodyMap.get("reporterName"));
                    put("mobile", requestBodyMap.get("reporterPhone"));
                    put("idcard", requestBodyMap.get("reporterIdNo"));
                }}), OpenApiUtil.readPublicKey(publicKey)));
                put("carInfo", OpenApiUtil.RSAEncryptOAEP(CommonUtils.toJSONString(new HashMap<String, Object>(){{
                    put("carNo", requestBodyMap.get("vehicleNo"));
                    put("carModel", requestBodyMap.get("vehicleType"));
                    put("carVin", requestBodyMap.get("vin"));
                }}), OpenApiUtil.readPublicKey(publicKey)));
                put("addr", new HashMap<String, Object>(){{
                    put("province", requestBodyMap.get("caseProvince"));
                    put("city", requestBodyMap.get("caseCity"));
                    put("county", requestBodyMap.get("caseCounty"));
                    put("address", requestBodyMap.get("caseLocation"));
                    put("longitude", PublicUtil.isNotEmpty(requestBodyMap.get("caseLongitude")) ? Double.valueOf(requestBodyMap.get("caseLongitude").toString()) : null);
                    put("latitude", PublicUtil.isNotEmpty(requestBodyMap.get("caseLatitude")) ? Double.valueOf(requestBodyMap.get("caseLatitude").toString()) : null);
                }});
                put("desAddr", new HashMap<String, Object>(){{
                    put("province", requestBodyMap.get("desState"));
                    put("city", requestBodyMap.get("desCity"));
                    put("county", requestBodyMap.get("desCounty"));
                    put("address", requestBodyMap.get("desAddress"));
                    put("longitude", PublicUtil.isNotEmpty(requestBodyMap.get("desLongitude")) ? Double.valueOf(requestBodyMap.get("desLongitude").toString()) : null);
                    put("latitude", PublicUtil.isNotEmpty(requestBodyMap.get("desLatitude")) ? Double.valueOf(requestBodyMap.get("desLatitude").toString()) : null);
                }});
            }};
            // logger.info("派单请求信息，orderNo=" + requestBodyMap.get("orderNo") + ",requestJson=" + param);
            String postParam = CommonUtils.toJSONString(param);
            System.out.println("请求参数="+postParam);
            return CommonUtils.doPost(allot_rescue_url, CommonUtils.toJSONString(param));
		} catch (Exception e) {
			return "{\"resultCode\":\"009\",\"message\":\"秘钥解析失败\"}";
		}
    }

    /**
     * @description 根据条件保存轨迹
     * @param orderNo 服务单号
     * @param trackType 轨迹类型
     * @param trackDesc 轨迹描述
     * @param status 状态
     * @param currentDate 当前时间
     * @param sourceName01 操作人
     * @return
     * @author wkangle
     * @time 2021/09/27 0027 16:39
     * @exception/throws
    */
    private void saveTrack(String orderNo, String trackType, String trackDesc, String status, Date currentDate, String sourceName01){
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);

        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(sourceName01);
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(sourceName01);
        orderTrackDao.insert(orderTrackEntity);
    }

    /**
     * @description 调用下游下单接口：如果返回请求超时，则需要多次请求下游，请求次数为3次，如三次都未请求成功，系统不再进行接口请求
     * @param orderNo 服务单号
     * @param operater 操作人
     * @param servicerId 服务商id
     * @param servicerName 服务商名称
     * @param ruleId 分发规则id
     * @param code 分发规则类型
     * @param url 请求地址
     * @param PD_PublicKey 下游公钥
     * @param requestBodyMap 请求参数
     * @return
     * @author wkangle
     * @time 2021/11/11 0011 9:35
     * @exception/throws
     */
    public void callCreateRescue(String orderNo, String operater, OrderMainEntity orderMainEntity, String servicerId, String servicerName, String ruleId, String code, String url, String PD_PublicKey, Map<String, Object> requestBodyMap) {
    	new Thread() {
			public void run () {
		    	Date currentDate = new Date();
		        String allotRescueResult = null;
		        Integer resultCode = null; // 响应码 0-成功 9999-超时异常
		        String message = null; // 响应内容
		        AtomicReference<Integer> counter = new AtomicReference<Integer>(0); // 用于记录循环次数
		        do {
		        	try {
		        		allotRescueResult = allotRescue(url, PD_PublicKey, requestBodyMap);
		        	} catch (Exception e) {
		        		logger.error("下单失败：请求下游异常", e);
		        		e.printStackTrace();
		        		resultCode = 9998;
		                message = "下单失败：请求下游异常";
		        	}
		            counter.getAndSet(counter.get() + 1);
		            logger.info("调用下游接口完成：orderNo:" + orderNo + ", 请求次数count:" + counter.get() + ", 响应result:" + allotRescueResult);
		            if (allotRescueResult != null) {
		                try {
		                    JSONObject resultObject = JSONObject.parseObject(allotRescueResult);
		                    resultCode = Integer.valueOf(PublicUtil.isNotEmpty(resultObject.get("resultCode")) ? resultObject.get("resultCode").toString() : null);
		                    message = PublicUtil.isNotEmpty(resultObject.get("message")) ? resultObject.get("message").toString() : null;
		                } catch (Exception e) {
		                	logger.error("下单失败：下游下单接口返回参数格式有误，解析异常", e);
		                    e.printStackTrace();
		                    resultCode = 9998;
		                    message = "下单失败：下游下单接口返回参数格式有误，解析异常";
		                }
		                if (resultCode == 0) {
		                	try {
			                    //1.记录轨迹
			                    currentDate = new Date();
			                    saveTrack(orderNo, "00", "调用下游["+servicerName+"]下单成功", "01", currentDate, operater); // 下单备注； 待处理
			                    orderMainEntity.setChildStatus("1");
			                    orderMainEntity.setUpdater(operater);
			                    orderMainEntity.setUpdateTime(new Date());
			                    orderMainEntity.setStatus("01");
			                    orderMainDao.update(orderMainEntity); // 更新服务单子状态
			                    //2.更新服务单的实际服务商信息
			                    Map<String, String> servicerMap = new HashMap<>();
			                    servicerMap.put("orderNo", orderNo);
			                    servicerMap.put("servicerId", servicerId);
			                    servicerMap.put("servicerName", servicerName);
			                    orderServiceProviderDao.updateServicer(servicerMap);
			                    //3.更新记录规则轮询数
			                    if("888".equals(code)){
			                    	//此处是车牌号在最近下过单，直接给原来的救援商，不计入分发规则
			                    }else{
			                    	if("01".equals(code)){ //规则匹配到的，新增or更新t_rule_count数据
				                        //1.更新ruleId的数据count+1 //2.更新ruleId、servicerId的server_count+1，时间变更为当前时间
				                        int maxCount = ruleCountService.findMaxCountByRuleId(ruleId);
				                        if(maxCount==0){//说明此规则还没派发过，或者修改规则后，未派发过
				                            RuleCountEntity vo_temp = new RuleCountEntity();
				                            vo_temp.setDataId(UUID.randomUUID().toString().replace("-", ""));
				                            vo_temp.setRuleId(ruleId);
				                            vo_temp.setServicerId(servicerId);
				                            vo_temp.setServerCount(1);
				                            vo_temp.setCount(1);
				                            vo_temp.setVersion(0);
				                            vo_temp.setCreateTime(new Date());
				                            ruleCountService.insertVo(vo_temp);
				                        }else{
				                            Map<String,String> fenfa_param = new HashMap<>();
				                            fenfa_param.put("ruleId", ruleId);
				                            fenfa_param.put("servicerId", servicerId);
				                            RuleCountEntity ruleCountVo =  ruleCountService.queryOneByParam(fenfa_param);
				                            if(ruleCountVo==null){//说明当前服务商未派发过，或者修改规则后，未派发过
				                                RuleCountEntity vo = new RuleCountEntity();
				                                vo.setDataId(UUID.randomUUID().toString().replace("-", ""));
				                                vo.setRuleId(ruleId);
				                                vo.setServicerId(servicerId);
				                                vo.setServerCount(1);
				                                vo.setCount(maxCount);
				                                vo.setVersion(0);
				                                vo.setCreateTime(new Date());
				                                ruleCountService.insertVo(vo);
				                            }else{//更新操作
				                                ruleCountVo.setServerCount(ruleCountVo.getServerCount()+1);
				                                ruleCountVo.setCreateTime(new Date()); //当前操作时间
				                                ruleCountVo.setCount(maxCount);
				                                ruleCountService.updateVo(ruleCountVo);
				                            }
				                            //根据ruleId，将count++
				                            ruleCountService.updateCount(ruleId);
				                        }
				                    }else{//服务商信息匹配到的，新增or更新t_servicer_count数据
				                        Map<String, String> servicer_param = new HashMap<>();
				                        servicer_param.put("servicerId", servicerId);
				                        ServicerCountEntity servicerCountVo = servicerCountService.queryOneByParam(servicer_param);
				                        if(servicerCountVo==null){//新增
				                            ServicerCountEntity v = new ServicerCountEntity();
				                            v.setDataId(UUID.randomUUID().toString().replace("-", ""));
				                            v.setServicerId(servicerId);
				                            v.setCount(1);
				                            v.setCreateTime(new Date());
				                            servicerCountService.insertVo(v);
				                        }else{//修改
				                            servicerCountVo.setCreateTime(new Date());
				                            servicerCountService.updateVo(servicerCountVo);
				                        }
				                    }
			                    }
		                	} catch (Exception e) {
		                		logger.error("下单失败：下游下单成功，本地处理异常", e);
		                		e.printStackTrace();
		                		resultCode = 9998;
		                        message = "下单失败：下游下单成功，本地处理异常";
		                	}
		                    break;
		                }
		            } else { //接口响应为null
		                // 记录轨迹
		                currentDate = new Date();
		                saveTrack(orderNo, "00", "调用下游["+servicerName+"]下单失败：下单接口返回为null", "01", currentDate, operater); // 下单备注； 待处理
		                orderMainEntity.setChildStatus("0");
		                orderMainEntity.setUpdater(operater);
		                orderMainEntity.setUpdateTime(new Date());
		                orderMainEntity.setStatus("00");
		                orderMainDao.update(orderMainEntity); // 更新服务单子状态
		                break;
		            }
		        } while (counter.get() < 3 && resultCode == 9999); // 请求次数小于3 且异常为超时异常时，重新发起下单请求

		        if(PublicUtil.isNotEmpty(allotRescueResult) && resultCode != 0) {
		        	currentDate = new Date();
		        	// 修改主表状态
		        	orderMainEntity.setChildStatus("0");
		            orderMainEntity.setUpdater(operater);
		            orderMainEntity.setUpdateTime(new Date());
		            orderMainEntity.setStatus("00");
		            orderMainDao.update(orderMainEntity); // 更新服务单子状态
		            // 修改订单服务商表，清楚下游服务商信息
		            Map<String, String> servicerMap = new HashMap<>();
	                servicerMap.put("orderNo", orderMainEntity.getOrderNo());
	                orderServiceProviderDao.clearInfo(servicerMap);
	                // 记录轨迹
		        	if (resultCode == 9999) {
		        		// 请求响应不为空且请求异常为超时异常时，服务单状态根据最后一次请求结果记录
			            saveTrack(orderNo, "00", "调用下游["+servicerName+"]下单失败：请求超时", "01", currentDate, operater); // 下单备注； 待处理
			        } else {
			            saveTrack(orderNo, "00", "调用下游["+servicerName+"]下单失败：" + message, "01", currentDate, operater); // 下单备注； 待处理
			        }
		        }
			}
    	}.start();
    }

}
